/**
 * 
 */
package dataflowscheme.engine.ui;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
import org.eclipse.jdt.internal.debug.ui.SWTFactory;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.dialogs.ResourceListSelectionDialog;

import dataflowscheme.engine.core.launching.IDFConstants;

/**
 * 
 * @author <a href="mailto:misiak7@gmail.com">Michal Antolik</a>
 *
 */
@SuppressWarnings("restriction")
public class DFSMainTab extends AbstractLaunchConfigurationTab {

	private Text fProgramText;
	private Button fProgramButton;
	Button fPrintStatsCheckButton;
	
	private Text fLog4jText;
	private Button fLog4jButton;
	private Combo fLog4jLevelCombo;
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getName()
	 */
	public String getName() {
		return "DF Main";
	}

	/**
	 * Open dialog for select data-flow scheme
	 */
	protected void handleSearchButtonSelected() {
		DFSchemeResourceListSelectionDialog dialog = new DFSchemeResourceListSelectionDialog(getShell(), ResourcesPlugin.getWorkspace().getRoot(), IResource.FILE);
		dialog.setTitle("Dataflow schemes");
		dialog.setMessage("Select DF scheme");
		if (dialog.open() == Window.OK) {
			Object[] files = dialog.getResult();
			IFile file = (IFile) files[0];
			fProgramText.setText(file.getFullPath().toString());
		}
		
	}
	
	/**
	 * Open dialog for select data-flow scheme
	 */
	protected void handleLog4jSearchButtonSelected() {
		Log4jResourceListSelectionDialog dialog = new Log4jResourceListSelectionDialog(getShell(), ResourcesPlugin.getWorkspace().getRoot(), IResource.FILE);
		dialog.setTitle("Log4j properties");
		dialog.setMessage("Select Log4j properites file");
		// TODO: single select
		if (dialog.open() == Window.OK) {
			Object[] files = dialog.getResult();
			IFile file = (IFile) files[0];
			fLog4jText.setText(file.getFullPath().toString());
		}
		
	}

	/**
	 * create controls for DF Main Tab
	 */
	public void createControl(Composite parent) {
		Font font = parent.getFont();
		
		Composite comp = new Composite(parent, SWT.NONE);
		setControl(comp);
		GridLayout topLayout = new GridLayout();
		topLayout.verticalSpacing = 0;
		topLayout.numColumns = 3;
		comp.setLayout(topLayout);
		comp.setFont(font);
		
		createVerticalSpacer(comp, 3);
		
		Group group= new Group(comp, SWT.NONE);
		group.setText("Dataflow Scheme"); 
		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
		group.setLayoutData(gd);
		GridLayout layout = new GridLayout();
		layout.numColumns = 2;
		group.setLayout(layout);
		group.setFont(font);
		
		fProgramText = new Text(group, SWT.SINGLE | SWT.BORDER);
		gd = new GridData(GridData.FILL_HORIZONTAL);
		fProgramText.setLayoutData(gd);
		fProgramText.setFont(font);
		fProgramText.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				updateLaunchConfigurationDialog();
			}
		});
		
		fProgramButton = createPushButton(group, "&Browse...", null); //$NON-NLS-1$
		fProgramButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				handleSearchButtonSelected();
			}
		});

		createVerticalSpacer(comp, 3);
		
		group= new Group(comp, SWT.NONE);
		group.setText("Engine Properties"); 
		gd = new GridData(GridData.FILL_HORIZONTAL);
		group.setLayoutData(gd);
		layout = new GridLayout();
		layout.numColumns = 5;
		group.setLayout(layout);
		group.setFont(font);
		
		//first row
		Label logLevelLabel = SWTFactory.createLabel(group, "Use log4j logging level", font, 0);
		gd = new GridData(GridData.FILL_HORIZONTAL);
		gd.horizontalSpan = 4;
		logLevelLabel.setLayoutData(gd);
		fLog4jLevelCombo = SWTFactory.createCombo(group, 0, 1, new String[]{"DEBUG", "INFO", "WARN", "ERROR", "OFF"});
		fLog4jLevelCombo.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				updateLaunchConfigurationDialog();
			}
		});


		//second row
		fPrintStatsCheckButton = SWTFactory.createCheckButton(group, "Compute and print Statistics", null, false, 2);
		fPrintStatsCheckButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				updateLaunchConfigurationDialog();
			}
		});
		gd = new GridData(GridData.FILL_HORIZONTAL);
		gd.horizontalSpan = 5;
		fPrintStatsCheckButton.setLayoutData(gd);
		
		SWTFactory.createLabel(group, "Use custom log4j properties file", font, 0);

		fLog4jText = new Text(group, SWT.SINGLE | SWT.BORDER);
		gd = new GridData(GridData.FILL_HORIZONTAL);
		fLog4jText.setLayoutData(gd);
		fLog4jText.setFont(font);
		fLog4jText.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				updateLaunchConfigurationDialog();
			}
		});
		gd = new GridData(SWT.FILL, SWT.CENTER, true, false);
		gd.horizontalSpan = 3;
		fLog4jText.setLayoutData(gd);
		
		fLog4jButton = createPushButton(group, "&Browse...", null); //$NON-NLS-1$
		fLog4jButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				handleLog4jSearchButtonSelected();
			}
		});	

		
		
		
		
		setControl(comp);
	}

	public void performApply(ILaunchConfigurationWorkingCopy configuration) {
		String program = fProgramText.getText().trim();
		if (program.length() == 0) {
			program = null;
		}
		configuration.setAttribute(IDFConstants.ATTR_DF_SCHEME, program);	
		
		//log level
		String logLevelText = fLog4jLevelCombo.getItem(fLog4jLevelCombo.getSelectionIndex());;
		configuration.setAttribute(IDFConstants.ATTR_DF_SCHEME_LOGLEVEL, logLevelText);	
		
		//print stats
		if(fPrintStatsCheckButton.getSelection()){
			configuration.setAttribute(IDFConstants.ATTR_DF_SCHEME_STATS, "YES");
		} else {
			configuration.setAttribute(IDFConstants.ATTR_DF_SCHEME_STATS, "NO");
		}
		
		//log4j properties file
		String log4jProp = fLog4jText.getText().trim();
		configuration.setAttribute(IDFConstants.ATTR_DF_SCHEME_LOG4JFILE, log4jProp);
	}

	public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
	}

	class DFSchemeResourceListSelectionDialog extends ResourceListSelectionDialog{

		public DFSchemeResourceListSelectionDialog(Shell parentShell,
				IContainer container, int typeMask) {
			super(parentShell, container, typeMask);
		}
		
		/**
	     * Adjust the pattern string for matching.
	     */
	    protected String adjustPattern() {
	    	String text = super.adjustPattern();
	    	return text + ".dataflowscheme";
	    }
		
	}
	
	class Log4jResourceListSelectionDialog extends ResourceListSelectionDialog{

		public Log4jResourceListSelectionDialog(Shell parentShell,
				IContainer container, int typeMask) {
			super(parentShell, container, typeMask);
		}
		
		/**
	     * Adjust the pattern string for matching.
	     */
	    protected String adjustPattern() {
	    	String text = super.adjustPattern();
	    	return text + ".properties";
	    }
		
	}

	public void initializeFrom(ILaunchConfiguration configuration) {
		try {
			String program = configuration.getAttribute(IDFConstants.ATTR_DF_SCHEME, (String)null);
			if (program != null) {
				fProgramText.setText(program);
			}
			
			String logLevel = configuration.getAttribute(IDFConstants.ATTR_DF_SCHEME_LOGLEVEL, (String)null);
			if (logLevel != null) {
				int logLevelIndex = 0;
				if(logLevel.equals("INFO")){
					logLevelIndex = 1;
				} else if(logLevel.equals("WARN")){
					logLevelIndex = 2;
				} else if(logLevel.equals("ERROR")){
					logLevelIndex = 3;
				} else if(logLevel.equals("OFF")){
					logLevelIndex = 4;
				}
				fLog4jLevelCombo.select(logLevelIndex);
			} else {
				fLog4jLevelCombo.select(1);
			}
			
			String log4jProp = configuration.getAttribute(IDFConstants.ATTR_DF_SCHEME_LOG4JFILE, (String)null);
			if (log4jProp != null) {
				fLog4jText.setText(log4jProp);
			}
			
			String stats = configuration.getAttribute(IDFConstants.ATTR_DF_SCHEME_STATS, (String)null);
			if (stats != null) {
				if(stats.equals("YES")){
					fPrintStatsCheckButton.setSelection(true);
				} else {
					fPrintStatsCheckButton.setSelection(false);
				}
			} else {
				fPrintStatsCheckButton.setSelection(true);
			}
		} catch (CoreException e) {
			setErrorMessage(e.getMessage());
		}		
	}
}